﻿using MicroConfig.NetCore.Server.Models;
using MicroConfig.NetCore.Server.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MicroConfig.NetCore.Server
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class AuthFilterAttribute : ActionFilterAttribute
    {
        public AuthFilterAttribute()
        {
        }

        /// <summary>
        /// 是否可匿名访问
        /// </summary>
        public bool Anonymous { get; set; }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            //由于Filters是套娃模式，使用以下逻辑保证作用域的覆盖 Action > Controller > Global
            if (context.Filters.OfType<AuthFilterAttribute>().Last() != this)
            {
                return;
            }
            if (Anonymous) return;
            bool isLogin = false;

            if (context.HttpContext.Request.Cookies.TryGetValue("_auth_", out string token))
            {
                var str = EncryptHelper.DecryptString(token);
                var parts = str.Split("___");
                if (parts.Length == 2)
                {
                    var user = UserService.Instance.Single(parts[0], parts[1]);
                    isLogin = user != null;
                }
            }

            var isAjaxRequest = "XMLHttpRequest".Equals(context.HttpContext.Request.Headers["X-Requested-With"].FirstOrDefault(), StringComparison.OrdinalIgnoreCase);

            if (!isLogin)
            {
                if (isAjaxRequest)
                {
                    var ro = new ResultObject
                    {
                        Msg = "nologin"
                    };
                    context.Result = new JsonResult(ro);
                }
                else
                {
                    context.Result = new RedirectResult("/home/login");
                }
            }

            base.OnActionExecuting(context);
        }
    }
}
